#include "details.hpp"
#include "path.hpp"
#include <iostream>
#include <cassert>
#include <set>
using namespace easyfs;

namespace test_path
{
    void test01()
    {
        path p1("/Users/yyo/Project/easylog/unittest");

        path p2(p1);

        path p3("");
        p3 = p1;
        p3.assign("asdfasdf");

        std::cout << p1 << std::endl;
        std::cout << p2 << std::endl;
        std::cout << p3 << std::endl;

        path p4;
    }

    void test02()
    {
        path p1("easylog/");
        path p2("include/");

        std::cout << (p1 + p2) << std::endl;
        std::cout << (p1 + "include/") << std::endl;

        p1 += p2;
        std::cout << p1 << std::endl;

        p2 += "easylog/";
        std::cout << p2 << std::endl;
    }

    void test03()
    {
#if defined (__linux__) || defined (__APPLE__)
        path p("/Users/yyo/Project/easylog/unittest/test.cc");
#else
        path p("C:\\Users\\yyo\\Project\\easylog\\unittest\\test.cc");
#endif

        p.replace_extension(".hpp");
        std::cout << p << std::endl;    
        
        p.replace_filename("path.hpp");
        std::cout << p << std::endl;
        
        p.remove_filename();
        std::cout << p << std::endl;
    }

    void test04()
    {
#if defined (__linux__) || defined (__APPLE__)
        path p("/Users/yyo/Project/easylog/unittest/test.cc");
#else
        path p("C:\\Users\\yyo\\Project\\easylog\\unittest\\test.cc");
#endif
        std::cout << p.parent_path() << std::endl;

        std::cout << p.filename() << std::endl;
        std::cout << p.stem() << std::endl;
        std::cout << p.extension() << std::endl;

        path rp("test.cc");
        std::cout << rp.absolute_path() << std::endl;
        path ap = rp.absolute_path();
        std::cout << ap.relative_path() << std::endl;
    }

    void test05()
    {
        std::cout << current_path() << std::endl;
    }
}

namespace test_details 
{
    void test01()
    {
        path p1("test.cc");
        path p2("test.hh");

        std::cout << exists(p1) << std::endl;
        std::cout << exists(p2) << std::endl;

        std::cout << is_directory(".") << std::endl;
        std::cout << is_file("test.cc") << std::endl;
        std::cout << is_file(".") << std::endl;
        std::cout << is_directory("test.cc") << std::endl;

        path p3("aaa");
#if defined (__linux__) || defined (__APPLE__)
        path p4("aaa/bbb/ccc");
#else
        path p4("aaa\\bbb\\ccc");
#endif
        create_directory(p3);
        create_directory(p4);

        remove(p4);
        // remove(p3); // aaa/bbb, cause error
    }

    void test02()
    {
        create_file("a.txt");
        move("a.txt", "b.txt");

        create_directory("dir");
        move("b.txt", "dir");

        create_directory("dir.dst");
        move("dir", "dir.dst");

        create_file("test.txt");
        write_file("test.txt", "hello world");
        std::cout << read_file("test.txt") << std::endl;
        std::cout << file_size("test.txt") << std::endl;

        auto ps = scan_directory(".", true);
        for (auto& p : ps)
            std::cout << p << std::endl;

        std::cout << "------------------------" << std::endl;

        ps = recursive_scan_directory(".");

        std::set<path> set;
        for (auto& p : ps)
        {
            assert(set.insert(p).second);
            std::cout << p << std::endl;
        }
    }

    void test03()
    {
        create_file("test.txt");
        remove(path("test.txt"));
        create_directory("empty_dir");
        remove(path("empty_dir"));

#if defined (__linux__) || defined (__APPLE__)
        create_directory("dir1/dir2");
        create_file("dir1/dir2/test.txt");
#else
        create_directory("dir1\\dir2");
        create_file("dir1\\dir2\\test.txt");
#endif
        remove_all(path("dir1"));

        create_file("test.txt");
        write_file("test.txt", "hello world");
        clear("test.txt");

#if defined (__linux__) || defined (__APPLE__)
        create_directory("dir1/dir2");
        create_file("dir1/dir2/test.txt");
#else
        create_directory("dir1\\dir2");
        create_file("dir1\\dir2\\test.txt");
#endif
        clear("dir1");
    }

    void test04()
    {
        create_file("test.txt");
        write_file("test.txt", "hello world");
        copy("test.txt", "test.txt.cp");
#if defined (__linux__) || defined (__APPLE__)
        create_directory("dir1/dir2");
        create_file("dir1/dir2/test.txt");
        write_file("dir1/dir2/test.txt", "hello world");
#else
        create_directory("dir1\\dir2");
        create_file("dir1\\dir2\\test.txt");
        write_file("dir1\\dir2\\test.txt", "hello world");
#endif
        create_directory("dir");
        copy("dir", "dir.cp");
    }

    void test05()
    {
        create_file("test.txt");
        write_file("test.txt", "hello\nworld\nsuccess\n");
        std::cout << line_number("test.txt") << std::endl;

        std::cout << last_access_time("test.txt") << std::endl;
        std::cout << last_change_time("test.txt") << std::endl;
        std::cout << last_modify_time("test.txt") << std::endl;
    }
}

int main()
{
    using namespace 
        // test_path;
        test_details;
    
#define NUMBER \
                    5

    switch (NUMBER)
    {
    case 1: test01(); break;
    case 2: test02(); break;
    case 3: test03(); break;
    case 4: test04(); break;
    case 5: test05(); break;
    }

    return 0;
}
